// Can I define a generic container, and also define a child class,
// with proper iterators?
// It's hard!

#include <list>
#include <iostream>
#include <fstream>

class Collection_Iter;

class Collection {
public:

    virtual ~Collection();

    typedef Collection_Iter iterator;
    typedef ptrdiff_t difference_type;
    typedef size_t size_type;
    typedef int value_type;
    typedef int * pointer;
    typedef int & reference;

    // Iterator handling:
    virtual Collection_Iter begin() {return Collection_Iter(*this,0);}
    virtual Collection_Iter end() {return Collection_Iter(*this,0);}

    void write(std::ostream& os);

    friend class Collection_Iter;
};

class Collection_Iter {
public:
    typedef Collection_Iter iterator;
    typedef ptrdiff_t difference_type;
    typedef size_t size_type;
    typedef int value_type;
    typedef int * pointer;
    typedef int & reference;

public:
    Collection_Iter(Collection& col, int index) {};
    int& operator*() {return 0;}
    virtual Collection_Iter operator++() {return *this;}
    virtual Collection_Iter operator++(int) {return this;}
};

void Collection::write(std::ostream& os) {
    for (Collection_Iter iter = begin(); iter != end(); iter++)
        os << *iter << " ";
    os << "\n";
}

class Collection_List : public Collection {
private:
    std::list<int> items;

    void add(int x);
    Collection_Iter begin();
    Collection_Iter end();
};

class Collection_List_Iter : public Collection_Iter {
private:
    Collection_List &collection;
    std::list<int>::iterator iter;

    Collection_List_Iter(Collection_List& col, int index);

public:
    int& operator*();
    iterator operator++();
    iterator operator++(int);
};

void Collection_List::add(int x) {
    items.push_back(x);
}

Collection_Iter Collection_List::begin() {
    return Collection_List_Iter(*this, 0);
}

Collection_Iter Collection_List::end() {
    return Collection_List_Iter(*this, items.size());
}

Collection_List_Iter::Collection_List_Iter(Collection_List& col, int index)
    : collection(col) {
    if (index == 0)
        iter = col.items.begin();
    else if (index == col.items.size())
        iter = col.items.end();
    return *this;
}

int& Collection_List_Iter::operator*() {
    return *iter;
}

Collection_List_Iter Collection_List_Iter::operator++() {
    iter++;
    return *this;
}

Collection_List_Iter Collection_List_Iter::operator++(int) {
    Collection clone(*this);
    iter++;
    return clone;
}

int main() {
    Collection *col = new Collection_List();

    col->add(1);
    col->add(2);
    col->add(3);

    col->write(std::cout);
}

